﻿using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

namespace Nemerle.Data
{
  //[DebuggerNonUserCode]
  //[System.Serializable]
#if !NET_4_0
  //[Nemerle.MarkOptions (System.Serializable)]    
#endif
  //[Nemerle.MarkOptions (DebuggerNonUserCode)]    
  public variant Either[L, R]
  {
    | Left { val : L; }
    | Right { val : R; }

    public override ToString() : string
    {
      match (this){
        | Left  (x) => "Left(" + x.ToString() + ")"
        | Right (x) => "Right(" + x.ToString() + ")"
      }
    }
  }
  
  public module Eithers
  {
    public Either[L, R, RT](
      lf : L -> RT, 
      rf : R -> RT
    ) : Either[L, R] -> RT
    {
      x => {
        | Either.Left(l)  => lf(l)
        | Either.Right(r) => rf(r)
      }
    }
    
    public Either[L, R, RL, RR](
      lf : L -> RL, 
      rf : R -> RR
    ) : Either[L, R] -> Either[RL, RR]
    {
      x => {
        | Either.Left(l)  => Either.Left(lf(l))
        | Either.Right(r) => Either.Right(rf(r))
      }
    }
  }
}
